package online.hxstart.code.concurrent.chapter08;

import java.util.LinkedList;

/**
 * @author huxing
 * @date 2019/7/11 星期四 14:23
 * @describe
 */
public class LinkedRunnableQueue implements RunnableQueue {

  /**
   * 任务队列的最大容量，在构造时传入
   */
  private final int limit;

  /**
   * 若任务队列已经满了 则需要执行拒绝策略
   */
  private final DenyPolicy denyPolicy;

  /**
   * 存放任务队列
   */
  private final LinkedList<Runnable> runnableLinkedList = new LinkedList<>();

  /**
   * 线程池
   */
  private final ThreadPool threadPool;

  public LinkedRunnableQueue(int limit, DenyPolicy denyPolicy, ThreadPool threadPool) {
    this.limit = limit;
    this.denyPolicy = denyPolicy;
    this.threadPool = threadPool;
  }

  @Override
  public void offer(Runnable runnable) {
    synchronized (runnableLinkedList) {
      if (runnableLinkedList.size() >= limit) {
        denyPolicy.reject(runnable, threadPool);
      } else {
        runnableLinkedList.addLast(runnable);
        runnableLinkedList.notifyAll();
      }
    }
  }

  @Override
  public Runnable take() throws InterruptedException {
    synchronized (runnableLinkedList) {
      while (runnableLinkedList.isEmpty()) {
        runnableLinkedList.wait();
      }
      return runnableLinkedList.removeFirst();
    }
  }

  @Override
  public int size() {
    synchronized (runnableLinkedList) {
      return runnableLinkedList.size();
    }
  }
}
